package dao

import (
	"database/sql"
	"errors"
	"fmt"
	"log"
	"time"
)

type OrderReq struct {
	UserID   int    `json:"user_id" binding:"required"`
	Location string `json:"location" binding:"required"`
	CarID    []int  `json:"car_id" binding:"required"`
}

type OrderRes struct {
	OrderID     int                      `json:"order_id"`
	UserID      int                      `json:"user_id"`
	Location    string                   `json:"location"`
	OrderAmount float64                  `json:"order_amount"`
	CreateTime  time.Time                `json:"create_time"`
	SuccessTime time.Time                `json:"success_time"`
	OrderStatus int                      `json:"order_status"`
	Data        []map[string]interface{} `json:"data"`
}

type Temp struct {
	OrderID     int ``
	CarID       int
	UserID      int       ``
	OrderAmount float64   ``
	Location    string    ``
	CreateTime  time.Time ``
	SuccessTime time.Time
	UniqueNun   int
	GoodID      int
	Color       string
	Parm        string
	Price       float64
	Num         int
	Status      int
	Image       string
}

func CreateOrderId(uid int, location string) (orderId int, create_time time.Time, err error) {
	sqlStr := "call create_orderid(?, ?)"
	row := DB.QueryRow(sqlStr, uid, location)
	err = row.Scan(&orderId, &create_time)
	if err != nil {
		fmt.Println(err)
		return 0, create_time, err
	}
	return
}

func CreateOrder(orderInfo OrderReq, orderId int) (total float64, err error) {
	var carid []int
	carid = orderInfo.CarID
	total, err = IFOrderInfoRight(orderInfo)
	if err != nil {
		DB.Exec("delete from order_db where order_id = ?", orderId) //删除订单编号
		fmt.Println("delete from order_db:", err)
		return
	}
	sqlUpdate := "update order_db set total = ? WHERE order_id = ?" //更新订单金额
	_, err = DB.Exec(sqlUpdate, total, orderId)
	if err != nil {
		DB.Exec("delete from order_db where order_id = ?", orderId) //删除订单编号
		fmt.Println("update order_db set total = ? ", err)
		return
	}

	sqlStr := "insert into order_middle values (?, ?)" //
	prepare, err := DB.Prepare(sqlStr)
	if err != nil {
		fmt.Println("insert into order_middle values ", err)
		return
	}
	for _, value := range carid {
		_, err = prepare.Exec(orderId, value)
		if err != nil {
			fmt.Println("prepare.Exec(sqlStr, orderId, value)", err)
			return
		}
	}
	return
}

func IFOrderInfoRight(orderInfo OrderReq) (total float64, err error) {
	total = 0
	var carid []int
	carid = orderInfo.CarID
	fmt.Println("carid  :", carid)
	sqlStr := "select price*num from car where car.user_id = ? && car.id = ? && car.status != 0"
	prepare, err := DB.Prepare(sqlStr)
	defer prepare.Close()
	if err != nil {
		return
	}
	for _, value := range carid {
		var temp float64
		fmt.Println("IFOrderInfoRight：", value)
		row := prepare.QueryRow(orderInfo.UserID, value)
		err = row.Scan(&temp)
		if err != nil {
			fmt.Println(err)
		}
		fmt.Println("temp :", temp)
		if temp == 0 {
			err = errors.New("CAR_INFO_NOT_RIGHT")
			return 0, err
		}
		total = total + temp
	}
	return
}

func QueryOrder(orderId string) (orderInfo OrderRes) {
	//sqlStr :=
	//	"SELECT om.order_id, car_id, od.user_id, total, location, " +
	//		"create_time, success_time, unique_num, " +
	//		"good_idfk, colorfk, parmfk, price, num, `order_status`, u.image " +
	//		"FROM order_middle om, order_db od, car c ,unique_id u" +
	//		"WHERE om.order_id = od.order_id && om.car_id = c.id && om.order_id = ? && c.status != 0 " +
	//		"&& c.unique_num = u.`unique`;"
	sqlStr := "SELECT om.order_id, car_id, od.user_id, total, location, create_time, success_time, unique_num, c.good_idfk, colorfk, parmfk, price, num, `order_status`, u.image \n" +
		"FROM order_middle om, order_db od, car c ,unique_id u \n" +
		"WHERE om.order_id = od.order_id && om.car_id = c.id && om.order_id = ? && c.`status` != 0 && c.unique_num = u.`unique`;"
	log.Println(sqlStr)
	rows, err := DB.Query(sqlStr, orderId)
	defer rows.Close()
	if err != nil {
		fmt.Println(err)
		return
	}
	for rows.Next() {
		var temp Temp
		err = rows.Scan(
			&temp.OrderID, &temp.CarID, &temp.UserID, &temp.OrderAmount, &temp.Location,
			&temp.CreateTime, &temp.SuccessTime, &temp.UniqueNun,
			&temp.GoodID, &temp.Color, &temp.Parm, &temp.Price, &temp.Num, &temp.Status, &temp.Image)
		if err != nil {
			fmt.Println(err)
			return
		}
		orderInfo.OrderID = temp.OrderID
		orderInfo.Location = temp.Location
		orderInfo.CreateTime = temp.CreateTime
		orderInfo.SuccessTime = temp.SuccessTime
		orderInfo.OrderAmount = temp.OrderAmount
		orderInfo.OrderStatus = temp.Status
		orderInfo.UserID = temp.UserID
		mapTemp := map[string]interface{}{
			"car_id":     temp.CarID,
			"unique_num": temp.UniqueNun,
			"good_id":    temp.GoodID,
			"color":      temp.Color,
			"parm":       temp.Parm,
			"price":      temp.Price,
			"num":        temp.Num,
			"image":      temp.Image,
		}
		orderInfo.Data = append(orderInfo.Data, mapTemp)
	}
	return
}

func CancelOrder(oid string) (err error) {
	var count int
	row := DB.QueryRow("select count(*) from order_db where order_id = ? && order_status = 1", oid)
	err = row.Scan(&count)
	if err != nil {
		fmt.Println("CancelOrder err: ", err)
		return
	}
	if count == 0 {
		err = errors.New("PARM IS NOT RIGHT")
		return
	}

	sqlStr := "call cancel_order(?)"
	resrow, err := DB.Exec(sqlStr, oid)
	if err != nil {
		fmt.Println(err)
		return
	}
	much, err := resrow.RowsAffected()
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("much is, ", much)
	if much == 0 {
		err = errors.New("PARM IS NOT RIGHT")
		return
	}
	return
}

func PayOrder(uid, oid string) (err error) {
	var code int
	sqlStr := "call pay_order(?, ?)"
	row := DB.QueryRow(sqlStr, oid, uid)
	err = row.Scan(&code)
	if row.Err() != nil {
		fmt.Println(row.Err())
		return
	}

	if err != nil {
		fmt.Println(err)
		return
	}
	if code == 0 {
		err = errors.New("余额不足")
		return
	} else if code == 2 {
		err = errors.New("不是有效订单信息")
	}
	return
}

func QueryUserOrder(uid string, code string) (orderInfoAll []OrderRes) {
	sqlStr := ""
	if code == "" {
		sqlStr =
			"SELECT om.order_id, car_id, od.user_id, total, location, " +
				"create_time, success_time, unique_num, " +
				"c.good_idfk, colorfk, parmfk, price, num, `order_status`, u.image " +
				"FROM order_middle om, order_db od, car c, unique_id u " +
				"WHERE om.order_id = od.order_id && om.car_id = c.id && od.user_id = ? && c.unique_num = u.`unique`;"
	} else {
		sqlStr =
			"SELECT om.order_id, car_id, od.user_id, total, location, " +
				"create_time, success_time, unique_num, " +
				"c.good_idfk, colorfk, parmfk, price, num, `order_status`, u.image " +
				"FROM order_middle om, order_db od, car c ,unique_id u " +
				"WHERE om.order_id = od.order_id && om.car_id = c.id " +
				"&& od.user_id = ? && od.order_status = ? && c.unique_num = u.`unique`;"
	}
	var rows *sql.Rows
	var err error
	if code == "" {
		fmt.Println("code = ", 3)
		rows, err = DB.Query(sqlStr, uid)
	} else {
		fmt.Println("code = ?", code)
		rows, err = DB.Query(sqlStr, uid, code)
	}

	defer rows.Close()
	if err != nil {
		fmt.Println(err)
		return
	}
	var orderInfo OrderRes
	for rows.Next() {
		var temp Temp
		log.Println(temp.Status)
		err = rows.Scan(
			&temp.OrderID, &temp.CarID, &temp.UserID, &temp.OrderAmount, &temp.Location,
			&temp.CreateTime, &temp.SuccessTime, &temp.UniqueNun,
			&temp.GoodID, &temp.Color, &temp.Parm, &temp.Price, &temp.Num, &temp.Status, &temp.Image)
		if err != nil {
			fmt.Println(err)
			return
		}
		if orderInfo.OrderID != temp.OrderID && orderInfo.OrderID != 0 {
			orderInfo = OrderRes{}
		}
		orderInfo.OrderID = temp.OrderID
		orderInfo.Location = temp.Location
		orderInfo.CreateTime = temp.CreateTime
		orderInfo.SuccessTime = temp.SuccessTime
		orderInfo.OrderAmount = temp.OrderAmount
		orderInfo.OrderStatus = temp.Status
		log.Println(temp.Status)
		orderInfo.UserID = temp.UserID
		mapTemp := map[string]interface{}{
			"car_id":     temp.CarID,
			"unique_num": temp.UniqueNun,
			"good_id":    temp.GoodID,
			"color":      temp.Color,
			"parm":       temp.Parm,
			"price":      temp.Price,
			"num":        temp.Num,
			"image":      temp.Image,
		}
		orderInfo.Data = append(orderInfo.Data, mapTemp)
		if len(orderInfoAll) == 0 { //等于0添加
			orderInfoAll = append(orderInfoAll, orderInfo)
		} else if orderInfoAll[len(orderInfoAll)-1].OrderID != orderInfo.OrderID {
			orderInfoAll = append(orderInfoAll, orderInfo)
		} else if orderInfoAll[len(orderInfoAll)-1].OrderID == orderInfo.OrderID {
			orderInfoAll[len(orderInfoAll)-1] = orderInfo
		}
	}
	return
}
